<template>
  <div>
    <div class="top-handle">
      <el-button type="primary" size="small" @click="saveSet">保存配置</el-button>
      <el-button type="primary" size="small" @click="startGather">开始采集</el-button>
      <el-button type="primary" size="small" @click="goBack">返回</el-button>
      <el-switch v-model="flowStatus" title="流程图开关" active-text="流程图" />
    </div>
    <div class="url-handle">
      <el-input v-model="url" :disabled="true" size="small" style="width:700px;" />
      <el-button icon="el-icon-refresh" title="刷新" size="small" type="success" @click="iframeReload" />
      <el-button v-if="false" icon="el-icon-sort" size="small" type="success" />
    </div>
    <!-- 流程步骤图 -->
    <div class="flow">
      <el-steps v-if="flowStatus" :active="fieldsList.length" space="300">
        <el-step v-for="(step,index) in fieldsList" :key="index">
          <template slot="title">
            <i class="el-icon-delete" style="cursor:pointer;" title="删除" @click="deleteStep(index,null,step,'p')" />
          </template>
          <template slot="description">
            <p style="max-width:100px;margin:0px;word-break:break-all;">{{ handleType[step.type] }}</p>
            <el-steps v-if="step.steps && step.steps.length" :active="step.steps.length" space="300">
              <el-step v-for="(item,idx) in step.steps" :key="idx">
                <template slot="title">
                  <i class="el-icon-delete" style="cursor:pointer;" title="删除" @click="deleteStep(index,idx,item,'c')" />
                </template>
                <template slot="description">
                  <p style="max-width:100px;margin:0px 10px 0px 0px;word-break:break-all;">{{ handleType[item.type] }}</p>
                </template>
              </el-step>
            </el-steps>
          </template>
        </el-step>
      </el-steps>
    </div>
    <div v-if="false">
      {{ config }}
    </div>
    <iframe id="myIframe" :src="url" frameborder="0" name="urlbox" style="width:100%;height:500px;" @onload="iframeChange" />
    <!-- 操作提示框 -->
    <div v-if="!handleFlag" class="handle-left">
      <i class="el-icon-d-arrow-left" @click="handleFlag = true" />
    </div>
    <div v-drag class="handle-box" :style="{'right':handleFlag?'0px':'-2000px'}">
      <div class="title">操作提示 <i class="el-icon-d-arrow-right fr-center" @click="handleFlag = false" /> </div>
      <div class="handle-body">
        <div class="handle-title"><i class="el-icon-warning" type="warning" /> 请选择页面元素
          <el-button v-if="backUrl != url && backUrl" type="primary" size="mini" @click="backToPrev">返回</el-button>
        </div>
        <div>
          <ul v-if="currentDom != null" class="handle-list" @click="handleOptionType">
            <li v-if="currentDom != null && currentDom.list" class="handle-option" data-type="list">列表类型</li>
            <li v-if="currentDom != null && currentDom.url" class="handle-option" data-type="clickHold">点击该元素(保留原页)</li>
            <li v-if="currentDom != null && currentDom.url" class="handle-option" data-type="clickDrop">点击该元素(放弃原页)</li>
            <li class="handle-option" data-type="next">循环点击下一页</li>
            <li v-if="currentDom != null && currentDom.tagName === 'INPUT'" class="handle-option" data-type="input">在该元素中输入</li>
            <li class="handle-option" data-type="text">采集所有文本(包括子节点文本)</li>
            <li class="handle-option" data-type="ownText">采集自身文本</li>
            <li class="handle-option" data-type="innerHtml">采集该元素innerHtml</li>
            <li class="handle-option" data-type="outerHtml">采集该元素outerHtml</li>
          </ul>
        </div>
        <!-- 编辑Xpath -->
        <div style="margin:5px">
          <el-input v-if="currentDom != null" v-model="currentDom.xpath" type="textarea" size="mini" :autosize="true" placeholder="Xpath编辑" />
        </div>
        <div class="field-list">
          <div>
            <div v-for="(item,index) in showFieldList" :key="index" style="display:inline-block;">
              <div v-if="item.type !== 'click'" class="field-item">
                <el-select v-model="item.field" size="mini">
                  <el-option v-for="field in modelFields" :key="field.id" :label="field.desc" :value="field.field" />
                </el-select>
                <div v-if="false" class="field-name">
                  <input v-if="item.edit" v-model="item.field" type="text" class="filed-text">
                  <span v-if="!item.edit" class="text-hidden filed-text">{{ item.field }}</span>
                  <i v-if="!item.edit" class="el-icon-edit pointer" @click="handleField('edit',index)" />
                  <i v-if="!item.edit" class="el-icon-delete pointer" @click="handleField('delete',index)" />
                  <i v-if="item.edit" class="el-icon-check pointer" @click="handleField('sure',index)" />
                </div>
                <div class="field-value" :title="item.content">{{ item.content }}</div>
              </div>
            </div>
          </div>
          <div style="overflow:auto;">
            <p style="color:blue;white-space:nowrap;">{{ currentDom && currentDom.content }}</p>
          </div>
        </div>
      </div>
    </div>
    <!-- 输入类型时 弹窗输入要填写的信息 -->
    <el-dialog
      :visible="inputFlag"
      :show-close="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      title="输入类型填写内容"
    >
      <el-form size="small" label-width="70px">
        <el-form-item label="填写内容">
          <el-input v-model="inputVal" placeholder="请输入要填写的内容" />
        </el-form-item>
        <div slot="footer">
          <el-button size="small" type="primary" @click="sureInput">确定</el-button>
        </div>
      </el-form>
    </el-dialog>
    <!-- 选择采集页数 -->
    <el-dialog
      :visible.sync="pageFlag"
      :show-close="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      title="采集页数配置"
    >
      <el-form ref="pageForm" :model="pageInfo" size="small" label-width="80px">
        <el-form-item prop="pageNum" label="分页页数" :rules="[{required:true,message:'请填写采集页数',trigger:'blur'}]">
          <el-input v-model="pageInfo.pageNum" type="number" placeholder="请填写采集列表页数" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="cancelPageNum">取消</el-button>
        <el-button type="primary" @click="surePageNum('pageForm')">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { PROJECT_API, MODEL_API } from '@/api/index'
export default {
  name: 'SetTask',
  data() {
    return {
    //   url: 'https://www.yaofangwang.com',
    //   url: 'http://wjw.beijing.gov.cn/zwgk_20040/',
      // url: 'http://www.nhc.gov.cn/xcs/yqtb/list_gzbd.shtml',
      // http://www.nhc.gov.cn/xcs/yqtb/list_gzbd.shtml
      url: '',
      backUrl: '', // 返回上一页
      flowStatus: false,
      handleType: {
        list: '列表类型',
        clickHold: '点击该元素(保留原页)',
        clickDrop: '点击该元素(放弃原页)',
        next: '循环点击下一页',
        input: '在该元素中输入',
        text: '采集所有文本(包括子节点文本)',
        ownText: '采集自身文本',
        innerHtml: '采集该元素innerHtml',
        outerHtml: '采集该元素outerHtml',
        data: '采集信息'
      },
      taskInfo: { },
      fieldsList: [],
      currentDom: null, // 当前操作的字段DOM
      handleFlag: true,
      inputFlag: false, // 填写类型
      inputVal: '',
      modelFields: [], // 选用字段模板下属字段
      showFieldList: [],
      pageInfo: { // 循环点击下一页页数
        pageNum: 0
      },
      pageFlag: false, // 页面弹窗
      config: ''
    }
  },
  mounted() {
    const id = this.$route.query.projectId
    const modelId = this.$route.query.modelId
    this.getFieldsByModelId(modelId)
    this.getCurrentProjectInfo(id)
    window.addEventListener('message', this.handler, false)
  },
  beforeDestroy() {
    window.removeEventListener('message', this.handler, false)
  },
  methods: {
    getCurrentProjectInfo(id) { // 获取当前设置任务信息
      PROJECT_API.getProjectInfoById(id).then(res => {
        const info = _.cloneDeep(res.data)
        this.url = info.sourceNet
        info.dispatch = JSON.parse(info.dispatch)
        info.groupId = parseInt(info.groupId)
        this.taskInfo = info
      })
    },
    getFieldsByModelId(id) { // 获取当前任务使用的字段模板下的字段
      MODEL_API.modelProperties(id).then((res) => {
        this.modelFields = res.data
      })
    },
    handler(e) { // 处理函数
      if (e.data === 'urlChange') return false
      if (window.location.href !== this.url) {
        let parseData = null
        if (typeof e.data === 'string' && /^\{\S|\s*\}$/g.test(e.data)) {
          parseData = JSON.parse(e.data)
        } else {
          parseData = e.data
        }
        if (parseData.hasOwnProperty('xpath') && parseData.xpath != null) {
          this.currentDom = parseData
          this.currentDom.originalXpath = parseData.xpath
        }
      }
    },
    iframeChange(e) { // iframe地址发生改变
      console.log('load')
      console.log(e)
    },
    handleOptionType(e) { // 设置元素采集类型
      const type = e.target.dataset.type
      this.currentDom.type = e.target.dataset.type
      this.currentDom.key = e.target.dataset.type
      const currentDom = _.cloneDeep(this.currentDom)

      //   先处理list类型，即上一步选取类型为list,以后的用selector对比，判断是否为列表中需要采集的内容
      const lastOne = this.fieldsList[this.fieldsList.length - 1]
      if (this.fieldsList.length > 0) {
        if (currentDom.originalXpath.includes(lastOne.originalXpath) && lastOne.type === 'list') {
          lastOne.steps.push(currentDom)
          if (type.startsWith('click')) {
            //   判断当前url与点击要跳转的url是否相同
            if (this.url !== currentDom.url && currentDom.url) {
              //  当为点击类型时，跳转页面
              // eslint-disable-next-line no-undef
              this.backUrl = this.url // 将老地址赋予返回地址
              this.url = _.cloneDeep(currentDom).url
            }
          }
          return false
        }
      }
      const gatherType = ['text', 'ownText', 'innerHtml', 'outerHtml']
      //   对每种采集类型做分别处理
      if (type.startsWith('click')) {
        //   判断当前url与点击要跳转的url是否相同
        if (this.url !== currentDom.url && currentDom.url) {
        //  当为点击类型时，跳转页面
        // eslint-disable-next-line no-undef
          this.backUrl = this.url // 将老地址赋予返回地址
          this.url = currentDom.url
        }
        this.fieldsList.push(currentDom)
      } else if (type === 'list') {
        currentDom.steps = []
        this.fieldsList.push(currentDom)
      } else if (type === 'input') {
        this.inputFlag = true
      } else if (gatherType.includes(type)) {
        if (lastOne && lastOne.type === 'list') {
          // 判断最后一个为list类型步骤是否已含有data类型
          // eslint-disable-next-line no-unused-vars
          let theIndex
          const hasData = lastOne.steps.some((step, index) => {
            if (step.type === 'data') { // 找到当步骤类型等于data是索引
              theIndex = index
            }
            return step.type === 'data'
          })
          if (hasData) { // 当当前list类型的步骤中已经有data类型
            lastOne.steps[theIndex].data.fields.push(currentDom)
          } else {
            lastOne.steps.push({
              type: 'data',
              data: { 'fields': [currentDom] }
            })
          }
        } else {
          this.fieldsList.push(currentDom)
        }
        // 如果为采集类型，将改采集字段放入展示数组中
        this.showFieldList.push(currentDom)
      } else if (type === 'next') {
        this.pageFlag = true
        this.fieldsList.push(this.currentDom)
      }
    },
    sureInput() { // input类型时，输入确定
      this.currentDom.val = this.inputVal
      this.fieldsList.push(this.currentDom)
      this.inputFlag = false
    },
    cancelPageNum() { // 取消页码配置
      this.pageFlag = false
      this.pageInfo.pageNum = 0
    },
    surePageNum(name) { // 确定页码配置
      this.$refs[name].validate(valid => {
        if (valid) {
          this.currentDom.num = this.pageInfo.pageNum
          this.pageFlag = false
        }
      })
    },
    saveSet() { // 保存设置返回列表
      const info = _.cloneDeep(this.taskInfo)
      const fields = _.cloneDeep(this.fieldsList)
      const config = {}
      config.source = info.sourceNet
      config.steps = fields
      console.log(config)
      this.config = config
      PROJECT_API.saveTaskConfig(config, info.id).then(res => {
        this.$message({ type: 'success', message: '保存成功', center: true })
      })
    },
    goBack() { // 返回任务列表
      this.$router.push('/index')
    },
    backToPrev() { // 返回列表页
      this.url = this.backUrl
    },
    startGather() { // 设置完成开始采集
    },
    iframeReload() { // 刷新iframe
      const _iframe = document.getElementById('myIframe')
      _iframe.src = this.url
    },
    handleField(type, index) { // 采集字段相关编辑
      if (type === 'edit') {
        this.fieldsList[index].edit = true
      } else if (type === 'delete') {
        this.fieldsList.splice(index, 1)
      } else {
        this.fieldsList[index].edit = false
      }
    },
    deleteStep(parentIndex, childIndex, step) { // 删除操作步骤
      this.$confirm('确定要删除此采集字段吗？', '系统提示').then(() => {
        if (childIndex == null) {
          if (this.fieldsList[parentIndex].originalXpath === step.originalXpath) {
            this.fieldsList.splice(parentIndex, 1)
          }
        } else {
          if (this.fieldsList[parentIndex].steps[childIndex].originalXpath === step.originalXpath) {
            this.fieldsList[parentIndex].steps.splice(childIndex, 1)
          }
        }
      }).catch(() => {

      })
    }
  }
}
</script>
<style lang="scss" scoped>
.fr-center{
    float: right;
    transform: translateY(50%);
    margin-right: 20px;
    cursor: pointer;
}
.pointer{
    cursor: pointer;
}
.text-hidden{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.url-handle {
    margin-top: 10px;
}
.handle-left{
    display: inline-block;
    position: absolute;
    right: 0;
    top: 0;
    width: 30px;
    height: 30px;
    background: yellow;
    box-sizing: border-box;
    padding-left: 7px;
    padding-top: 7px;
}
.handle-box{
    display: inline-block;
    width: 350px;
    position: absolute;
    right: 0px;
    top: 80px;
    border: 1px solid #cccccc;
    height: 300px;
    border-radius: 3px;
    overflow: hidden;
    background: #ffffff;
    .title{
        height: 40px;
        background: yellow;
        cursor: move;
        line-height: 40px;
        text-align: center;
    }
    .handle-body{
        max-height: 260px;
        background: white;
        overflow: auto;
        .handle-title{
            text-align: center;
            margin: 5px;
        }
        .handle-list{
            .handle-option{
                cursor: pointer;
                color: #108AC6;
            }
        }
        .field-list{
            overflow: auto;
            .field-item{
                display: inline-block;
                width: 150px;
                border:1px solid #000000;
                .filed-text{
                    display: inline-block;
                    width: 70%;
                }
                .field-value{
                    height: 20px;
                    border-top: 1px solid #000000;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }
            }

        }
    }
}
.flow{
    margin: 20px 0px;
}
</style>
